package co.fitstart.admin.web.controller.finance;

import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.demo2do.core.support.Page;
import com.demo2do.core.support.Result;
import com.demo2do.core.utils.CollectionUtils;
import com.demo2do.core.utils.JsonUtils;
import com.demo2do.core.web.resolver.Preloading;
import com.demo2do.core.web.utils.WebUtils;

import co.fitstart.admin.entity.security.Login;
import co.fitstart.admin.service.DataService;
import co.fitstart.admin.service.OrderService;
import co.fitstart.admin.service.PrincipalService;
import co.fitstart.admin.web.interceptor.MenuSetting;
import co.fitstart.admin.web.resolver.Secure;
import co.fitstart.admin.web.view.ExcelTemplateView;
import co.fitstart.entity.finance.ExchangeRate;
import co.fitstart.entity.finance.OrderInvoiceRecord;
import co.fitstart.entity.principal.Principal;

@Controller
@RequestMapping("/invoice-records")
@MenuSetting("menu-finance")
public class InvoiceController {
    
    @Autowired
    private OrderService orderService;
    
    @Autowired
    private PrincipalService principalService;
    
    @Autowired
    @Qualifier("dataService")
    private DataService<ExchangeRate> exchangeRateService;
    
    @Autowired
    @Qualifier("dataService")
    private DataService<OrderInvoiceRecord> orderInvoiceRecordService;
    
    private Logger logger = LoggerFactory.getLogger(InvoiceController.class);
    
    /**
     * 
     * @param page
     * @return
     */
    @RequestMapping(value = "", method = RequestMethod.GET)
    @MenuSetting("submenu-invoice-management")
    public ModelAndView list(@RequestParam(name = "invoice", required = false, defaultValue = "false") boolean invoice, 
                             @RequestParam(name = "export", required = false, defaultValue = "false") boolean export,
                             Page page,
                             HttpServletRequest request) {
        ModelAndView modelAndView = new ModelAndView("finance/invoice-record-list");
        
        List<OrderInvoiceRecord> invoiceRecords = orderService.listOrderInvoiceRecord(invoice, export, page);
        modelAndView.addObject("invoiceRecords", invoiceRecords);
        
        modelAndView.addObject("page", page);
        modelAndView.addObject("export", export);
        modelAndView.addObject("invoice", invoice);
        
        modelAndView.addObject("queryString", WebUtils.extractQueryString(request, "page"));
        
        return modelAndView;
        
    }
    
    /**
     * 
     * @param invoiceRecordId
     * @return
     */
    @RequestMapping(value = "/{invoiceRecordId}/edit", method = RequestMethod.GET)
    public ModelAndView edit(@PathVariable("invoiceRecordId") Long invoiceRecordId) {
        ModelAndView modelAndView = new ModelAndView("finance/invoice-record-edit");
        
        OrderInvoiceRecord orderInvoiceRecord = orderInvoiceRecordService.load(OrderInvoiceRecord.class, invoiceRecordId);
        
        modelAndView.addObject("orderInvoiceRecord", orderInvoiceRecord);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param orderInvoiceRecord
     * @return
     */
    @RequestMapping(value = "/{invoiceRecordId}", method = RequestMethod.PATCH)
    public @ResponseBody String onEdit(@Preloading("invoiceRecordId") OrderInvoiceRecord orderInvoiceRecord) {
        
        Result result = new Result();
        
        try {
            
            orderInvoiceRecordService.update(orderInvoiceRecord);
            
            result.success().message("修改成功");
            
        } catch (Exception e) {
            
            result.fail().message("修改失败");
            
            logger.error("#onEdit() error ", e);
            
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * 
     * @param invoiceRecordId
     * @return
     */
    @RequestMapping(value = "/{invoiceRecordId}/invoice", method = RequestMethod.GET)
    public ModelAndView invoice(@PathVariable("invoiceRecordId") Long invoiceRecordId) {
        ModelAndView modelAndView = new ModelAndView("finance/invoice-record-invoice");
        
        modelAndView.addObject("invoiceRecordId", invoiceRecordId);
        
        return modelAndView;
    }
    
    /**
     * 
     * @param orderInvoiceRecord
     * @return
     */
    @RequestMapping(value = "/{invoiceRecordId}/invoice", method = RequestMethod.PATCH)
    public @ResponseBody String onInvoice(@Preloading("invoiceRecordId") OrderInvoiceRecord orderInvoiceRecord) {
        
        Result result = new Result();
        
        try {
            
            orderInvoiceRecordService.update(orderInvoiceRecord.invoice());
            
            result.success().message("开票成功");
            
        } catch (Exception e) {
            
            result.fail().message("开票失败");
            
            logger.error("#onInvoice() error ", e);
            
        }
        
        return JsonUtils.toJsonString(result);
    }
    
    /**
     * 
     * @return
     */
    @RequestMapping(value = "/export-view", method = RequestMethod.GET)
    public ModelAndView export() {
        ModelAndView modelAndView = new ModelAndView("finance/invoice-record-export");
        
        return modelAndView;
        
    }
    
    /**
     * 
     * @param login
     * @return
     */
    @SuppressWarnings("unchecked")
    @RequestMapping(value = "/export", method = RequestMethod.GET)
    public ModelAndView onExport(@Secure Login login) {
        ModelAndView modelAndView = new ModelAndView(new ExcelTemplateView("invoice-record.xls"));
        
        // list all unexport student
        List<OrderInvoiceRecord> invoiceRecords = orderService.listOrderInvoiceRecord();
        modelAndView.addObject("invoiceRecords", invoiceRecords);
        
        Map<Long, Principal> managers = principalService.listSiteManager();
        modelAndView.addObject("managers", managers);
        
        List<ExchangeRate> exchangeRates = exchangeRateService.listAll(ExchangeRate.class);
        modelAndView.addObject("exchangeRate", exchangeRates.isEmpty() ? null : exchangeRates.get(0));
        
        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        modelAndView.addObject("fmt", format);
        
        
        // update student's exportArchives
        if(!invoiceRecords.isEmpty()) {
            List<Long> invoiceRecordIds = CollectionUtils.extractPropertyList(invoiceRecords, "id");
            orderService.exportInvoiceRecord(invoiceRecordIds, login.getId());
        }
        
        return modelAndView;
    }

}
